#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

/*
    通过信号灯，实现主线程先运行，子线程后运行
*/

//信号属性联合体
union semun {
    int              val;    /* Value for SETVAL */
    struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */
    unsigned short  *array;  /* Array for GETALL, SETALL */
    struct seminfo  *__buf;  /* Buffer for IPC_INFO
                                (Linux-specific) */
};

int sem_id;
union semun mysemun;
struct sembuf sops;

void *thread1(void *arg)
{
    sops.sem_op = -1;    //1：释放信号量，-1：分配信号量，0：等信号量变为0
    //分配信号量
    semop(sem_id, &sops, 1);
    for(int i=0;i<20;i++){
        printf("I am thread1\n");
    }
}

int main(int argc, char *argv[])
{
    //1.创建信号灯
    sem_id = semget(IPC_PRIVATE, 2, 0777);
    if(sem_id < 0){
        printf("信号灯创建失败！\n");
    }
    printf("信号灯创建成功！\n");
    // 查看信号灯
    system("ipcs -s");

    //2.设置信号灯
    mysemun.val = 0;  //设置信号值为0
    semctl(sem_id, 0, SETVAL, mysemun);

    //3.初始化信号属性
    sops.sem_num = 0;   //要操作的信号量的编号
    sops.sem_flg = 0;   //0：阻塞

    //4.创建线程
    pthread_t thread;
    pthread_create(&thread, NULL, thread1, NULL);
    
    for(int i=0;i<100;i++){
        printf("I am main\n");
    }
    sops.sem_op = 1;    //1：释放信号量，-1：分配信号量，0：等信号量变为0
    //释放信号
    semop(sem_id, &sops, 1);
    
    sleep(1);
    //删除信号灯
    semctl(sem_id, 0, IPC_RMID);
    //查看信号灯
    system("ipcs -s");

    return 0;
}


